<template>
  <div class="cesium-viewer-wapper">
    <div id="cesium-viewer" />
    <viewerSettingSidebar top="18em" :viewerSource="viewerSource" />
    <div class="tool-box-top-left">
      <div class="select-box-wrapper">
        <select-box :options="flyOptions" style="margin-right: 10px;" />
        <a-radio-group v-model:value="viewFrom" size="small" button-style="solid">
          <a-radio-button value="top" style="min-width: 4em;text-align: center;">top</a-radio-button>
          <a-radio-button value="side" style="min-width: 4em;text-align: center;">side</a-radio-button>
          <a-radio-button value="aircraft" style="min-width: 4em;text-align: center;">aircraft</a-radio-button>
        </a-radio-group>
      </div>
    </div>
    <GlobeRotater showTime :viewerSource="viewerSource" />
    <MousePosition show :viewerSource="viewerSource" />
  </div>
</template>

<script>
import Cesium from '@czm';
import { defineComponent, ref, watch, toRaw } from 'vue';
import { SelectBox, SliderBar } from '@components/widgets';
import { G3V } from '@g3x';
import { MousePosition, viewerSettingSidebar, GlobeRotater } from '@g3x/g3v/ui';
import { viewerMixin } from '@mixins';
import merge from '@g3x/utils/merge';
import { PolylineColorGlowMaterialProperty } from '@g3x/extends/czm';

// import czmPath from './path.js';

const $g3vOptions = {
  // defaultViewRectangle: G3V.defaultViews.global.china.rectangle,
  viewers: [
    {
      dom: 'cesium-viewer',
      name: 'viewer1',
      title: 'viewer#01',
      viewer: {
        imagery: { type: 'arcgisImagery', options: { brightness: 1, show: true } },
        imageryProvider: null,
        terrain: { type: 'default', options: { requestVertexNormals: true, requestWaterMask: true } },
        terrainProvider: null,
        shadows: false,
        scene3DOnly: true,
        // sceneMode: Cesium.SceneMode.SCENE2D,
        animation: false
      },
      layers: [
        { type: 'osmImagery', options: { brightness: 1, show: false } },
        { type: 'arcgisStreetMap', options: { brightness: 1, show: false } },
        { type: 'bingMapsImagery', options: { brightness: 1, show: false } },
        { type: 'tdtIboMap', options: { brightness: 1, show: false } },
        { type: 'tdtImgAnno', options: { brightness: 1, show: false } },
        {
          type: 'graticule',
          options: {
            brightness: 1,
            show: true
          }
        }
      ],
      globe: {
        depthTestAgainstTerrain: true,
        enableLighting: false //启用以太阳为光源的地球
      },
      bottomContainer: false,
      navigation: {
        // defaultResetView: G3V.defaultViews.global.china.rectangle ,
        defaultResetView: null //flyHome
      },
      shortcutAction: false,
      hideLayers: false
    }
  ]
};

export default defineComponent({
  name: 'flyPath', // 飞行动画
  mixins: [viewerMixin],
  components: { SelectBox, SliderBar, viewerSettingSidebar, GlobeRotater, MousePosition },
  props: {},
  setup() {
    const viewFrom = ref('');
    return { viewFrom };
  },
  data() {
    return {
      flyOptions: []
    };
  },
  computed: {},
  watch: {},
  methods: {
    g3vOptionsGet(original) {
      // const g3vOptions = merge($g3vOptions, true);
      return $g3vOptions;
    },
    onViewerInited() {
      console.log('fly onViewerInited');
    },
    initEffects() {
      const vm = this;
      const { viewer } = vm;
      const globe = viewer.scene.globe;

      const during = 180;

      //Set bounds of our simulation time
      var start = Cesium.JulianDate.fromDate(new Date(2015, 3, 25, 16));
      var stop = Cesium.JulianDate.addSeconds(start, during, new Cesium.JulianDate());

      //Make sure viewer is at the desired time.
      viewer.clock.startTime = start.clone();
      viewer.clock.stopTime = stop.clone();
      viewer.clock.currentTime = start.clone();
      viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; //Loop at the end
      viewer.clock.multiplier = 1;

      //Set timeline to simulation bounds
      // viewer.timeline.zoomTo(start, stop);

      //Set the random number seed for consistent results.
      Cesium.Math.setRandomNumberSeed(3);

      //Generate a random circular pattern with varying heights.
      function computeCirclularFlight(lon, lat, radius) {
        var property = new Cesium.SampledPositionProperty();
        for (var i = 0; i <= during; i += 20) {
          var radians = Cesium.Math.toRadians(i * 2);
          var time = Cesium.JulianDate.addSeconds(start, i, new Cesium.JulianDate());
          const [x, y] = [lon + radius * 1.5 * Math.cos(radians), lat + radius * Math.sin(radians)];
          // var position = Cesium.Cartesian3.fromDegrees(x, y, Cesium.Math.nextRandomNumber() * 500 + 1750);
          var position = Cesium.Cartesian3.fromDegrees(x, y, 2250);
          property.addSample(time, position);

          //Also create a point for each sample we generate.
          viewer.entities.add({
            position: position,
            point: {
              pixelSize: 7,
              color: Cesium.Color.RED,
              outlineColor: Cesium.Color.YELLOW,
              outlineWidth: 1
            }
          });
        }
        return property;
      }

      //Compute the entity position property.
      var position = computeCirclularFlight(-112.110693, 36.0994841, 0.03);

      const uniforms = {
        color: Cesium.Color.YELLOW.withAlpha(0.8),
        glowColor: Cesium.Color.RED.withAlpha(0.5),
        glowPower: 0.04
      };

      // const material = Cesium.Material.fromType('PolylineGlow');
      // const material = Cesium.Material.fromType('PolylineColorGlow',uniforms);
      // const material = new PolylineColorGlowMaterialProperty(uniforms);
      const material = new Cesium.MaterialProperty.fromType('PolylineColorGlow', uniforms);

      // var plane = new Cesium.Plane(Cesium.Cartesian3.UNIT_X, 0.0);

      function toInterval(options) {
        var start,stop;
        if(options.start){
          start = Cesium.JulianDate.fromIso8601(options.start)
          if(options.stop){
            stop = Cesium.JulianDate.fromIso8601(options.stop)
          }else if(options.during){
            stop = Cesium.JulianDate.addSeconds(start, during, new Cesium.JulianDate());
          }
        }
        const {isStartIncluded,isStopIncluded,data} = options
        return {
          start,stop,isStartIncluded,isStopIncluded,data
        }
      }

      function getAvailability(timeIntervals_) {
        const timeIntervals = [];
        timeIntervals_.forEach(e => {
          const interval = toInterval(e);
          var result = new Cesium.TimeInterval(interval);
          timeIntervals.push(result);
        });
        const availability = new Cesium.TimeIntervalCollection(timeIntervals);
        return availability;
      }

      const timeIntervals = [{ start: Cesium.JulianDate.toIso8601(start), during }];

      const availability = getAvailability(timeIntervals);

      // const availability = new Cesium.TimeIntervalCollection([
      //   new Cesium.TimeInterval({
      //     start,
      //     stop
      //   })
      // ]);

      //Actually create the entity
      const entityDef = {
        id: undefined,
        name: 'aircraft',
        // show: false,
        description: 'aircraft',
        //Set the entity availability to the same interval as the simulation time.
        availability,

        //Use our computed positions
        position,

        //Automatically compute orientation based on position movement.
        orientation: new Cesium.VelocityOrientationProperty(position),

        //Load the Cesium plane model to represent the entity
        model: {
          uri: '//zzgis.com/cdn/3d/SampleData/models/CesiumAir/Cesium_Air.glb',
          minimumPixelSize: 64
        },

        label: {
          text: 'aircraft',
          showBackground: true,
          horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM
        },

        // plane: plane,

        //Show the path as a pink line sampled in 1 second increments.
        path: {
          resolution: 0.2,
          width: 50,
          material
        }
      };

      var entity = viewer.entities.add(entityDef);

      // viewer.trackedEntity = entity;

      //Add button to view the path from the top down
      watch(
        () => vm.viewFrom,
        newVal => {
          switch (newVal) {
            case 'top': {
              viewer.trackedEntity = undefined;
              viewer.zoomTo(viewer.entities, new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-90)));
              break;
            }
            case 'side': {
              viewer.trackedEntity = undefined;
              viewer.zoomTo(viewer.entities, new Cesium.HeadingPitchRange(Cesium.Math.toRadians(-90), Cesium.Math.toRadians(-10), 10000));
              break;
            }
            case 'aircraft': {
              viewer.trackedEntity = entity;
              break;
            }
          }
        }
      );

      vm.viewFrom = 'aircraft';

      //Add a combo box for selecting each interpolation mode.
      this.flyOptions = [
        {
          text: 'Lagrange Polynomial',
          onselect: function() {
            entity.position.setInterpolationOptions({
              interpolationDegree: 5,
              interpolationAlgorithm: Cesium.LagrangePolynomialApproximation
            });
          }
        },
        {
          text: 'Hermite Polynomial',
          onselect: function() {
            entity.position.setInterpolationOptions({
              interpolationDegree: 2,
              interpolationAlgorithm: Cesium.HermitePolynomialApproximation
            });
          }
        },
        {
          text: 'Linear Approximation',
          onselect: function() {
            entity.position.setInterpolationOptions({
              interpolationDegree: 1,
              interpolationAlgorithm: Cesium.LinearApproximation
            });
          }
        }
      ];
      this.flyOptions[0].onselect();
    }
  }
});
</script>

<style lang="less">
.cesium-viewer-wapper {
  .tool-box-left-top {
    display: flex;
    button {
      min-width: 5em;
      background-color: rgba(0, 0, 0, 0.75);
      border-color: rgba(0, 0, 0, 0);
      cursor: pointer;
      transition: all 500ms;
      &:hover {
        opacity: 0.75;
      }
      &.active {
        background-color: rgba(0, 20, 200, 0.75);
      }
    }
  }
}
</style>
